iOS 宏(define)与常量(const)以及extern

###思考下,下面的有什么不同,分别在什么时候使用呢?

1
2
3
4
5
6
7
8
9
10

#define HSCoder @"汉斯哈哈哈"
NSString *HSCoder = @"汉斯哈哈哈";
extern NSString *HSCoder;
extern const NSString *HSCoder;

static const NSString *HSCoder = @"汉斯哈哈哈";

const NSString *HSCoder = @"汉斯哈哈哈";
NSString const *HSCoder = @"汉斯哈哈哈";

###当我们想全局共用一些数据时,可以用宏、变量、常量

宏:

1
#define HSCoder @"汉斯哈哈哈"

变量:

1
NSString *HSCoder = @"汉斯哈哈哈";

常量:

1
2
3
4
5
四种写法:
static const NSString *HSCoder = @"汉斯哈哈哈";
const NSString *HSCoder = @"汉斯哈哈哈";
NSString const *HSCoder = @"汉斯哈哈哈";
NSString * const HSCoder = @"汉斯哈哈哈";

宏:只是在预处理器里进行文本替换,没有类型,不做任何类型检查,编译器可以对相同的字符串进行优化。只保存一份到 .rodata 段。甚至有相同后缀的字符串也可以优化,你可以用GCC 编译测试,”Hello world” 与 “world” 两个字符串,只存储前面一个。取的时候只需要给前面和中间的地址,如果是整形、浮点型会有多份拷贝,但这些数写在指令中。占的只是代码段而已,大量用宏会导致二进制文件变大

变量:共享一块内存空间,就算项目中N处用到,也不会分配N块内存空间,可以被修改,在编译阶段会执行类型检查

常量:共享一块内存空间,就算项目中N处用到,也不会分配N块内存空间,可以根据const修饰的位置设定能否修改,在编译阶段会执行类型检查

###const和static const区分

1
2
3
4

const NSString *HSCoder = @"汉斯哈哈哈"; //本文件内部的全局常量

static const NSString *HSCoder = @"汉斯哈哈哈";//用static修饰后,不能提供外界访问,只能在本文件内访问,或者导入本文件可用(iOS中只有.h文件的导入,所以定义在.h中,如果导入.h头文件那么外部也可以用,如果定义在.m则只能在.m本文件内部使用)

###const修饰位置
const右边的总不能被修改

1
2
3
4
5
6
7
8
1.const NSString *HSCoder = @"汉斯哈哈哈";
"*HSCoder"不能被修改, "HSCoder"能被修改

2.NSString const *HSCoder = @"汉斯哈哈哈";
"*HSCoder"不能被修改, "HSCoder"能被修改

3.NSString * const HSCoder = @"汉斯哈哈哈";
"HSCoder"不能被修改,"*HSCoder"能被修改

“static作用”:

  • 修饰局部变量:

1.延长局部变量的生命周期,程序结束才会销毁。

2.局部变量只会生成一份内存,只会初始化一次。

3.改变局部变量的作用域。

  • 修饰全局变量

1.只能在本文件中访问,修改全局变量的作用域,生命周期不会改

2.避免重复定义全局变量

####const作用:限制类型

  • 1.const仅仅用来修饰右边的变量(基本数据变量p,指针变量*p)
  • 2.被const修饰的变量是只读的。

####”extern作用”:

  • 只是用来获取全局变量(包括全局静态变量)的值,不能用于定义变量
  • “extern工作原理”:
  • 先在当前文件查找有没有全局变量,没有找到,才会去其他文件查找。

知识补充:
对于指针a来说,*a就是指针a所指向的内存空间存储的值,&a就是存储这个变量的内存地址,a是指针名

staic和const联合的作用:声明一个静态的全局只读常量,在”一个文件中”经常使用的字符串常量,可以使用static与const组合

extern与const组合的作用:在”多个文件中”经常使用的同一个字符串常量,可以使用extern与const组合。

  • static与const组合:在每个文件都需要定义一份静态全局变量。
  • extern与const组合:只需要定义一份全局变量,多个文件共享